home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
301-325
/
disk_319
/
cnewssrc
/
uupc.lzh
/
uupc
/
dcp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-01-16
|
9KB
|
462 lines
/* dcp.c
*
* Revised edition of dcp
*
* Stuart Lynne May/87
*
* Copyright (c) Richard H. Lamb 1985, 1986, 1987
* Changes Copyright (c) Stuart Lynne 1987
*
* $Id: dcp.c,v 1.2 90/01/16 10:25:00 crash Exp Locker: crash $
*/
#ifndef lint
static char RCSid[] = "$Id: dcp.c,v 1.2 90/01/16 10:25:00 crash Exp Locker: crash $";
#endif /* lint */
/*
* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987
* This program implements a uucico type file transfer and remote
* execution type protocol.
*/
#include "dcp.h"
int pktsize; /* packet size for pro */
FILE *logfile; /* system log file */
FILE *syslog; /* transmission log file */
FILE *fw; /* cmdfile pointer */
char state; /* system state */
char cfile[80]; /* work file pointer */
int remote; /* -1 means we're remote ..7 */
int msgtime; /* timout setting */
char fromfile[132];
char hostfile[132]; /* host version of fromfile */
char tofile[132];
int fp; /* current disk file ptr */
int size; /* nbytes in buff */
FILE *fsys;
char Rmtname[20];
char rmtname[20];
char *cctime;
char proto[5];
/* char loginseq[256]; */
char sysline[BUFSIZ];
char s_systems[64];
char s_logfile[64];
char s_syslog[64];
char *flds[60];
int kflds;
extern int debuglevel; /* debugging flag */
unsigned int checksum();
/*
* new usage
*
* dcp [-xn] -r0 slave mode
* dcp [-xn] -shost call host
* dcp [-xn] -sall call all hosts
* dcp [-xn] call any hosts as required by C. files
*/
complain(s)
char *s;
{
fprintf(stderr, "Please set your %s environment variable.", s);
}
static void cant(file)
char *file;
{
fprintf(stderr, "Can't open: \"%s\"\n", file);
exit( NULL );
}
dcpmain( argc, argv )
int argc;
char *argv[];
{
FILE *ftmp;
char line[132];
#ifdef FJE
short inhibit_xqt = FALSE;
short goto_xqt = FALSE;
#endif /* FJE */
if (!name || !*name) {
complain(NAME);
exit( -1 );
}
if (!nodename || !*nodename) {
complain(NODENAME);
exit( -1 );
}
mkfilename(s_logfile, logdir, LOGFILE);
mkfilename(s_syslog, logdir, SYSLOG);
mkfilename(s_systems, confdir, SYSTEMS);
if ((logfile = FOPEN(s_logfile, "a", 't')) == NULL)
cant(s_logfile);
if ((syslog = FOPEN(s_syslog, "a", 't')) == NULL)
cant(s_syslog);
remote = MASTER;
debuglevel = 1;
fp = -1;
fw = (FILE *) NULL;
strcpy(Rmtname, "any");
while (--argc) {
if (**++argv == '-') {
switch(argv[0][1]) {
#ifdef FJE
case 'i': /* "-i" to disable DCXQT() */
inhibit_xqt = TRUE;
break;
case 'c': /* "-c" to jump down to DCXQT() */
goto_xqt = TRUE;
break;
#endif /* FJE */
case 'x':
debuglevel = atoi(argv[0]+2);
break;
case 's':
sprintf(Rmtname, "%.7s", argv[0]+2);
break;
case 'r':
remote = atoi(argv[0]+2);
break;
default:
break;
}
}
}
printmsg( 0, "remote = %d", remote);
printmsg( 0, "debuglevel = %d", debuglevel);
printmsg( 0, "Rmtname = %s", Rmtname);
if (goto_xqt)
goto try_dcxqt;
if (remote == MASTER) {
printmsg( 0, "Calling %s", Rmtname );
if (( fsys = FOPEN( s_systems, "r", 't' )) == (char *)NULL )
exit( FAILED );
state = 'I';
while (TRUE) {
printmsg( 4, "Mstate = %c", state );
switch (state) {
case 'I':
state = getsystem();
break;
case 'S':
state = callup();
break;
case 'P':
state = startup();
break;
case 'D':
state = master();
break;
case 'Y':
state = sysend();
break;
case 'G':
if ( strcmp( Rmtname, "any" ) != SAME )
state = 'Y';
else
state = 'I';
break;
}
if (state == 'A')
break;
}
fclose( fsys );
} else {
printmsg( 0, "Answering %s, speed %d", device, speed );
if (openline( device, speed ) == -1)
return(FALSE);
state = 'L';
while (TRUE) {
printmsg( 4, "Sstate = %c", state );
switch (state) {
case 'L':
state = login();
break;
case 'I':
state = startup();
break;
case 'R':
state = slave();
break;
case 'Y':
state = sysend();
break;
}
if (state == 'A')
break;
}
closeline();
}
/* scan and process any received files */
try_dcxqt:
if (!inhibit_xqt && dcxqt())
printmsg( 0, "ERROR in DCXQT" );
fclose( syslog );
fclose( logfile );
/*
* If we initiated a call (remote == MASTER) and the
* system responded without errors [or at least, without
* an ABORT code 'A'], return 1 to the shell.
*
* [The function sysend() returns 'I' if successful in
* terminating the connection. This allows the state
* machine to start over again with the next machine
* to call, although this isn't implemented :-]
*/
return( (remote == MASTER) && (state != 'A') );
}
/*
* master
*/
master()
{
state = 'I';
while (TRUE) {
printmsg( 4, "Top level state (master mode) %c", state );
switch (state) {
case 'I':
state = sinit();
break;
case 'B':
state = scandir();
break;
case 'S':
state = send();
break;
case 'Q':
state = sbreak();
break;
case 'G':
state = receive();
break;
case 'C':
state = 'Y';
break;
case 'Y':
state = endp();
break;
case 'P':
return('Y');
case 'A':
return('A');
default:
return('A');
}
}
}
/*
* slave
*/
slave()
{
state = 'I';
while (TRUE) {
printmsg( 4, "Top level state (slave mode) %c", state );
switch (state) {
case 'I':
state = rinit();
break;
case 'F':
state = receive();
break;
case 'C':
state = schkdir();
break;
case 'T':
state = 'B';
break;
case 'B':
state = scandir();
break;
case 'S':
state = send();
break;
case 'Q':
state = sbreak();
break;
case 'G':
return('Y');
case 'Y':
state = endp();
break;
case 'P':
return('Y');
case 'A':
return('A');
default:
return('A');
}
}
}
/*
* receive
*
* This is the state table switcher for receiving files.
*/
receive()
{
state = 'F'; /* Receive-Init is the start state */
while (TRUE) {
printmsg( 4, " receive state: %c", state );
switch (state) { /* Do until done */
case 'F':
state = rfile();
break; /* Receive-File */
case 'D':
state = rdata();
break; /* Receive-Data */
case 'C':
return('C'); /* Complete state */
case 'A':
return('Y'); /* "Abort" state */
default:
return('Y');
}
}
}
/*
* send
*
* Send is the state table switcher for sending files. It loops until
* either it finishes or an error is encountered. The routines called
* by send are responsible for changing the state.
*/
send()
{
fp = -1; /* reset file getter/opener */
state = 'F'; /* Send initiate is the start state */
while (TRUE) { /* Do this as long as necessary */
printmsg( 4, "send state: %c", state );
switch (state) {
case 'F':
state = sfile();
break; /* Send-File */
case 'D':
state = sdata();
break; /* Send-Data */
case 'Z':
state = seof();
break; /* Send-End-of-File */
case 'B':
return ('B'); /* Complete */
case 'A':
return ('Y'); /* "Abort" */
default:
return ('Y'); /* Unknown, fail */
}
}
}
/*
* A command formatter for DCP. RH Lamb
*
* sets up stdin and stdout on various machines
* There is NO command checking so watch what you send and who you
* let accsess your machine. "C rm /usr/*.*" could be executed.
*/
dcxqt()
{
int i;
char command[60], input[60], output[60], line[BUFSIZ];
char *cp;
printmsg( 2, "\n\nStarting XQT phase..." );
while (dscandir()) {
strcpy( line, cfile );
fw = FOPEN( line, "r", 'b' ); /* imported X file */
#if 0 /* Why? */
strcpy(cfile, line);
#endif
printmsg( 2, "dcxqt:%s %ld", cfile, fw );
input[0] = '\0';
output[0] = '\0';
command[0] = '\0';
while ( fgets( line, BUFSIZ, fw ) != (char *)NULL ) {
cp = index( line, '\n' );
if ( cp != (char *)NULL )
*cp = '\0';
printmsg( 8, "dcxqt: %s", line );
switch (line[0]) {
case 'U': /* User information */
break;
case 'I': /* File to use as stdin */
strcpy( input, &line[2] );
break;
case 'O': /* File to use as stdout */
strcpy( output, &line[2] );
break;
case 'C': /* Command to execute */
strcpy( command, &line[2] );
break;
case 'R': /* Hmmm, I don't remember this one */
break; /* Maybe error response file? with '!' notation? */
default :
break;
}
}
fclose( fw );
printmsg( 0, "xqt: %s\n", command );
shell( command, input, output, (char *)NULL );
unlink(cfile);
importpath( hostfile, input );
unlink(hostfile);
importpath( hostfile, output );
unlink(hostfile);
}
return(0);
}
/*
* printmsg
*
* Print error message on standard output if not remote.
*/
/* VARARGS2 */
printmsg(level, fmt, args)
int level;
char *fmt;
long args;
{
if ( debuglevel > level ) {
if ( remote == MASTER ) {
vprintf( fmt, &args );
fputc( '\n', stdout );
fflush(stdout);
}
vfprintf( logfile, fmt, &args );
fputc( '\n', logfile );
fflush(logfile);
}
}